package io.github.gcdd1993.jpa.codegen.render;

import io.github.gcdd1993.jpa.codegen.config.CodeGeneratorConfig;
import io.github.gcdd1993.jpa.codegen.config.ModuleConfig;
import io.github.gcdd1993.jpa.codegen.metadata.EntityInfo;
import io.github.gcdd1993.jpa.codegen.util.FreeMarkerUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author gaochen
 * Created on 2019/6/20.
 */
public class DefaultRender implements IRender {

    private final CodeGeneratorConfig config;

    private Map<String, RenderingResponse> lastRenderingResponseMap = new HashMap<>();

    public DefaultRender(CodeGeneratorConfig config) {
        this.config = config;
    }

    @Override
    public final RenderingResponse render(EntityInfo entityInfo, String module) {
        RenderingRequest renderingRequest = new RenderingRequest();

        renderingRequest.setLastRenderResponse(lastRenderingResponseMap);
        renderingRequest.setEntities(config.getEntityInfos());

        ModuleConfig moduleConfig = config.getModuleConfigMap().get(module);

        if("all".equals(moduleConfig.getType())){
            renderingRequest.setClassName(moduleConfig.getClassNameSuffix());
        }else {
            renderingRequest.setClassName(entityInfo.getClassName() + moduleConfig.getClassNameSuffix());
        }
        if("lower".equals(moduleConfig.getFileNameCase())){
            renderingRequest.setClassName(renderingRequest.getClassName().replaceAll("([a-z])([A-Z]+)", "$1-$2").toLowerCase());
        }else if("upper".equals(moduleConfig.getFileNameCase())){
            renderingRequest.setClassName(renderingRequest.getClassName().replaceAll("([a-z])([A-Z]+)", "$1_$2").toUpperCase());
        }

        String packageName = entityInfo.getPackageName().replace(config.getEntityFlag(), moduleConfig.getFlag());

        renderingRequest.setPackageName(packageName);
        if (StringUtils.isBlank(moduleConfig.getSavePath())) {
            renderingRequest.setSavePath("src/main/java/" + packageName.replace(".", "/") + "/");
        } else {
            renderingRequest.setSavePath(moduleConfig.getSavePath() + "/" + moduleConfig.getFlag() + "/");
        }
        renderingRequest.setFileSuffix("." + moduleConfig.getFileSuffix());
        renderingRequest.setFtlName(moduleConfig.getFtlName());

        renderingRequest.setFtlPath(config.getFtlPath());
        renderingRequest.setCover(config.isCover());

        renderingRequest.setEntity(entityInfo);

        renderingRequest.setAuthor(config.getAuthor());
        renderingRequest.setComments(config.getComments());
        renderingRequest.setDate(config.getDate());

        // fields ，只支持基本类型映射
        renderingRequest.setOtherParams(config.getOtherParams());
        renderingRequest.setClassExclude(Arrays.stream(moduleConfig.getClassExclude().split(",")).collect(Collectors.toSet()));

        // check for other imports
        renderingRequest.setImports(checkImports(entityInfo));

        // use freemarker to render code.
        RenderingResponse lastRenderingResponse = FreeMarkerUtils.process(renderingRequest);

        lastRenderingResponseMap.put(module, lastRenderingResponse);
        return lastRenderingResponse;
    }

    @Override
    public final RenderingResponse render(List<EntityInfo> entityInfos, String module) {
        return render(config.getEntityInfos().get(0), module);
    }

    private List<String> checkImports(EntityInfo entityInfo) {
        List<String> imports = new ArrayList<>();
        String packageName = entityInfo.getId().getPackageName();
        if (!"java.lang".equals(packageName)) {
            imports.add(packageName);
        }
        return imports;
    }

}
